#!/usr/bin/env ruby
#
#
# SleepMirror - A view on your sleep quality.
#
# This prototype will load or accept an image and slowly fade it in.
# Test is written giving the user instructions on what to do.
# Start time is captured.
# Keyboard (SDL) Events are examined, looking for :t or :f.
# End time is captured and elapsed time is computed.
# The key pressed triggers a message sayingcorrect or incorrect.
# The elapsed time is displayed.
# Then we loop until q, esc, or quit is requested.
#
# Version History:
# 01/18/2010 cgm: initial version.
#

#ORGIGINAL_STDOUT = $stdout
#$stdout = File.new("SleepMirrorLog.txt","w")

#Note to Self:  The OCRA build command is
#C:\Users\Gary\Documents\NetBeansProjects\sleepmirror\lib>ocra SleepMirror.rb * images\* dlls\*

main_dir = File.dirname(__FILE__)                  #get the directory we're in

Dir.chdir main_dir  # force the working directory to be where the script resides.  This is for Ocra expansion.
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), "includes")
#
#add the relative paths to find SDL
#before we include rubygame. Expect it to be "...Temp/ocrxxx.tmp/src/dlls"
SDL_PATHS = [ File.join( main_dir, "includes","")] #added the empty string to force an extra "\" at the end.
#SDL_PATHS = [ main_dir ]
#SDL_PATHS = { /windows/ => main_dir, /darwin/ => main_dir }


puts "**** main_dir = #{main_dir} \n and SDL LOAD PATH = #{SDL_PATHS} \n $: = #{$:}"


require "rubygame"
include Rubygame
include Rubygame::Events
include Rubygame::EventTriggers
include Rubygame::EventActions


# Initialize Rubygame, and clean up when script exits.
Rubygame.init
at_exit { Rubygame.quit }

DEFAULT_IMAGE = "Bars.jpg" # this is the default image to load if one is not provided on the command line.
# Decide which image file to load.
image_dir = File.join(File.dirname( __FILE__ ),"images")
file = File.expand_path( DEFAULT_IMAGE, image_dir ) # default file
if ARGV[0]
  file = File.expand_path( ARGV[0], image_dir )
else
  puts "You can pass an script to this file to load it."
end
puts "**** file = #{file}"
MAXALPHA = 255 # Maximum alpha value
ALPHASTEP = 1  # How much to dim/brighten the image
MINALPHA = 0   # Mimimum alpha value
INSTRUCTIONS1 = "Press any key as soon as you see any shape appear."
INSTRUCTIONS2 = "Press any key as soon as you see five shapes appear."

# wrap everything in a begin/resuce block to capture and log exceptions
#
#begin
  # your script here

  # Wrap this code in a "begin/rescue" block to recover from errors if
  # the image cannot be loaded.
  #
  begin

    # Load the image
    $image = Surface.load( file )
    $image.colorkey=$image.get_at([0,0])
    $image.alpha=0

    # Open a new Rubygame window to fit the image.
    $screen = Screen.open( $image.size,0,[HWSURFACE,SRCCOLORKEY,DOUBLEBUF] )
    $screen.title = "SleepMirror-prototype with " + File.basename(file)
    $screen.fill($image.colorkey) #Fill the screen with the image's background


  # Setup a clock to set framerate
  $clock = Clock.new
  $clock.target_framerate=(32)
  $clock.enable_tick_events
  $clock.calibrate


    # Blit ("paste") the image onto the screen.
    $image.blit( $screen, [0,0] )

  rescue SDLError, NoMethodError => e

    # Oops, load failed.
    puts "#{File.basename($0)}: Could not load image: #{file}"
    puts e.backtrace

    # Open a new Rubygame window
    $screen = Screen.open( [200,200] )
    $screen.title = "Load Error"

    # Fill with white
    $screen.fill( :white )

    # Thick red line from top left to bottom right.
    # Point [0,0] is the top left corner of the screen,
    # [200,200] is bottom right.
    #
    $screen.draw_polygon_s( [[ -5,   5], [  5,  -5],
        [205, 195], [195, 205]], :red )

    # Now from top right to bottom left.
    $screen.draw_polygon_s( [[195,  -5], [205,   5],
        [  5, 205], [ -5, 195]], :red )

  end


  # Set up an event handler to listen for events:
  #
  #  - Q or Escape keys press
  #  - Right mouse click inside the window
  #  - Window close button press
  #
  # When any of these events occurs, the "exit_script" method is called.
  #
  class MyHandler
    include Rubygame::EventHandler::HasEventHandler
  end

  handler = MyHandler.new
  handler.make_magic_hooks( :q            => :exit_script,
    :escape       => :exit_script,
    :mouse_right  => :exit_script,
    QuitRequested => :exit_script,
    :any          => :show_time
    #:t            => :show_time
  )
=begin  is_false_hook = EventHook.new( :owner => nil,
    :trigger => KeyPressTrigger.new(:f),
    :action  => MethodAction.new(:show_time))
  is_true_hook = EventHook.new(  :owner => nil,
    :trigger => KeyPressTrigger.new(:t),
    :action  => MethodAction.new(:show_time))
  handler.append_hook(is_false_hook) #Add the T/F hooks to the event table
  handler.append_hook(is_true_hook) #Add the T/F hooks to the event table
=end
  def make_dim
    $screen=Screen.new($image.size,0,[HWSURFACE])
    $screen.fill($image.colorkey)
    $image.alpha < ALPHASTEP ? $image.alpha=MINALPHA : $image.alpha -= ALPHASTEP
    $image.blit($screen,[0,0])
    puts "Dim: Image alpha now #{$image.alpha}"
  end
  def make_bright
    $screen=Screen.new($image.size,0,[HWSURFACE,SRCCOLORKEY,DOUBLEBUF])
    $screen.fill($image.colorkey)
    $screen.show_cursor=FALSE
    $image.alpha > MAXALPHA-ALPHASTEP ? $image.alpha=MAXALPHA : $image.alpha += ALPHASTEP
    #$image=$image.to_display_alpha
    $image.blit($screen,[0,0])


    TTF.setup()
    ttfont_path = File.join(File.dirname(__FILE__),"includes","FreeSans.ttf")
    ttfont = TTF.new( ttfont_path, 30 )
    result = ttfont.render( ($first_timing? INSTRUCTIONS2 : INSTRUCTIONS1),true,:blue)
    result.blit( $screen,[$image.size[0]/2-result.size[0]/2,5])
    #puts "Brighten: Image alpha now #{$image.alpha} colorkey #{$image.colorkey}"
  end
  def show_time (event)
    unless $first_timing
      $first_timing = Time.now - $t
      puts "1st timing= #{$first_timing}s" 
    else # $first_timing != 0.0 && $second_timing == 0.0
      $second_timing = Time.now - $t
      puts "2nd timing= #{$second_timing}"
      $screen=Screen.new($image.size,0,[HWSURFACE,SRCCOLORKEY,DOUBLEBUF])
      $screen.fill($image.colorkey)
      $screen.show_cursor=FALSE
      $image.alpha=255

      $image.blit($screen,[0,0])
      TTF.setup()
      ttfont_path = File.join(File.dirname(__FILE__),"includes","FreeSans.ttf")
      ttfont = TTF.new( ttfont_path, 24 )
      #result = ttfont.render( "You chose #{event.key.upcase}; that is #{event.key==:f ? "Correct!" : "incorrect."} Your time was #{elapsed_time}s.  Press Q or ESC to quit.", true, :white )
      result = ttfont.render( "Detection / Perception timings=#{$first_timing}s/#{$second_timing}s. Press Q or ESC to quit.", true, :white )
      result.blit( $screen,[$image.size[0]/2-result.size[0]/2,$image.size[1]/2])
      $answered = true    
    end
    

  end
  def exit_script
    #elapsed_time = Time.now - $t
    #puts "Elapased time #{elapsed_time}s"

    exit
  end

  $t=Time.now #Capture the starting time.
  $first_timing, $second_timing=nil #set the two timings to nil.
  $answered = false # Repeat this code until the user provides an answer.
  until $answered do
    #loop do

    # Fetch the user input events from SDL.
    events = Rubygame::Events.fetch_sdl_events
    events << make_bright

    # Pass each input to the event handler to check.
    events.each do |event|
      handler.handle( event )
    end

    $clock.tick

    # Refresh the screen
    #$screen.update()
    $screen.flip()
    # Pause for a while before checking for more events.
    sleep 0.1

  end

  #loop again until user signals exit
#  handler.remove_hook(is_false_hook) #Remove the hooks that cause the elapsed time to update
#  handler.remove_hook(is_true_hook) #This leaves on the hooks to exit on the event table

  loop do
    events = Rubygame::Events.fetch_sdl_events
    events.each do |event|
      handler.handle( event )
    end
  end

  #$stdout=ORIGINAL_STDOUT

=begin
rescue Exception => e
  File.open("except.log") do |f|
    f.puts e.inspect
    f.puts e.backtrace
  end
end
=end
